package pers.hl.module_main.bookshelf

import com.blankj.utilcode.util.ToastUtils
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.withContext
import pers.hl.common.base.BaseViewModel
import pers.hl.common.base.SingleLiveEvent
import pers.hl.lib_global.common.MMKVHelper
import pers.hl.lib_global.common.RouteUtils
import pers.hl.lib_global.http.LibResponse
import pers.hl.lib_global.model.bean.Book
import pers.hl.lib_global.model.bean.User

class BookShelfViewModel : BaseViewModel<BookShelfModel>() {

    var myBooksData = SingleLiveEvent<List<Book>>()

    /**
     * 我的书架，包含了两块数据(持有+借阅)，现在需要合并请求数据
     *
     */
    fun loadMyShelfBooks(): SingleLiveEvent<List<Book>> {
        launchOnUI {
            val user = MMKVHelper.getUser()
            if (user == null) {
                RouteUtils.navToLogin()
                ToastUtils.showShort("未获取到用户，请重新登录")
                return@launchOnUI
            }

            // 使用async
//            val myBooks = async(Dispatchers.IO) {
//                fetchMyBooks(user)
//            }
//            val myBorrows = async(Dispatchers.IO) {
//                fetchMyBorrowed(user)
//            }
//            val ownedBooks = mergeResult(myBooks, myBorrows)

            // 使用withContext
            val ownedBooks = fetchMyBooks(user)
            val borrowedBooks = fetchMyBorrowed(user)
            ownedBooks.addAll(borrowedBooks)
            myBooksData.value = ownedBooks
        }
        return myBooksData
    }

    private suspend fun mergeResult(
        myBooks: Deferred<MutableList<Book>>,
        myBorrows: Deferred<MutableList<Book>>
    ): MutableList<Book> {
        val a = myBooks.await()
        val b = myBorrows.await()
        a.addAll(b)
        return a
    }


    private suspend fun fetchMyBorrowed(user: User) =
        withContext(Dispatchers.IO) {
            val result = mModel.fetchMyBorrowed(user.userId)
            val record = result.data
            val list = mutableListOf<Book>()
            for (bookBorRec in record) {
                val book = bookBorRec.book
                book?.let { list.add(it) }
            }
            list
        }


    private suspend fun fetchMyBooks(user: User) =
        withContext(Dispatchers.IO) {
            val result: LibResponse<List<Book>> = mModel.loadMyBooks(user.userId)
            result.data.toMutableList()
        }

}